package ws

import (
	"github.com/gorilla/websocket"
	"go-jsmpeg-server/util"
)

// Play Response status
const (
	successStatus   = 20000
	failedStatus    = 40000
	contentTypeKey  = "content-type"
	applicationJson = "application/json"
)

type WsClientConn struct {
	Id    string
	Group string
	Conn  *websocket.Conn
	Send  chan []byte
}

type WsClientManager struct {
	clientGroup map[string]map[string]*WsClientConn
	register    chan *WsClientConn
	unRegister  chan *WsClientConn
	broadcast   chan *BroadcastData
}

type BroadcastData struct {
	groupId string
	data    []byte
}

var wsManager = WsClientManager{
	clientGroup: make(map[string]map[string]*WsClientConn),
	register:    make(chan *WsClientConn),
	unRegister:  make(chan *WsClientConn),
	broadcast:   make(chan *BroadcastData, 10),
}

// read message from websocket client, not use
func (c *WsClientConn) Read() {
	defer func() {
		wsManager.unRegister <- c
		c.Conn.Close()
	}()
	for {
		_, _, err := c.Conn.ReadMessage()
		if err != nil {
			break
		}
	}
}

// send message to websocket client
func (c *WsClientConn) Write() {
	defer func() {
		util.Logger().Infof("ws close group = %s. id = \n", c.Group, c.Id)
		c.Conn.Close()
	}()
	for {
		select {
		case message, ok := <-c.Send:
			if !ok {
				c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			c.Conn.WriteMessage(websocket.BinaryMessage, message)
		}
	}
}

func (manager *WsClientManager) registerClient(client *WsClientConn) {
	manager.register <- client
}

func (manager *WsClientManager) GroupBroadcast(group string, message []byte) {
	data := &BroadcastData{
		groupId: group,
		data:    message,
	}
	manager.broadcast <- data
}

func (manager *WsClientManager) StartWebSocketManager() {
	for {
		select {
		case client := <-manager.register:
			util.Logger().Infof("[register] Websocket connect clientId = %s\n", client.Id)
			if manager.clientGroup[client.Group] == nil {
				manager.clientGroup[client.Group] = make(map[string]*WsClientConn)
			}
			manager.clientGroup[client.Group][client.Id] = client
			util.Logger().Infof("[register] Register WS client %s to %s group success\n", client.Id, client.Group)
		case client := <-manager.unRegister:

			util.Logger().Infof("[Unregister] websocket client disconnect = %s\n", client.Id)

			if _, ok := manager.clientGroup[client.Group]; ok {

				close(client.Send)
				delete(manager.clientGroup[client.Group], client.Id)

				util.Logger().Infof("[Unregister] websocket client [%s] from group [%s] success\n", client.Id, client.Group)

				if len(manager.clientGroup[client.Group]) == 0 {
					util.Logger().Infof("[Unregister] Clear no client group [%s]\n", client.Group)
					delete(manager.clientGroup, client.Group)

					// go func() {
					// 	// 使用延迟处理,避免刷新网页的情况
					// 	// time.Sleep(time.Second)
					// 	// 使用延迟处理,避免刷新网页的情况
					// 	if len(manager.clientGroup[client.Group]) == 0 {
					// 		DeletePortMap(client.Group)
					// 	}
					// }()
				}
			}
		case data := <-manager.broadcast:
			if groupMap, ok := manager.clientGroup[data.groupId]; ok {
				for _, conn := range groupMap {
					conn.Send <- data.data
				}
			}
		}
	}
}
